package com.iplant.basic.utils;

import java.io.File;
import java.io.FileNotFoundException;
import java.nio.file.Files;
import java.util.*;

import com.iplant.base.utils.general.LockHelper;
import com.iplant.basic.service.basicenum.bfc.BFCAuthCompares;
import com.iplant.basic.service.basicenum.bpm.BPMEventModule;
import com.iplant.basic.service.bpm.BPMTaskService;
import com.iplant.basic.service.po.bfc.auth.BFCAuthRecord;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ResourceUtils;

import com.alibaba.fastjson.JSON;
import com.iplant.base.utils.SessionConstants;
import com.iplant.base.utils.serializer.CloneTool;
import com.iplant.base.utils.general.Configuration;
import com.iplant.base.utils.general.DesUtil;
import com.iplant.base.utils.general.StringUtils;
import com.iplant.base.utils.serializer.XmlTool;
import com.iplant.basic.service.po.bfc.BFCClientConfig;
import com.iplant.basic.service.po.bms.BMSEmployee;

public class Constants {

    private static final Logger logger = LoggerFactory.getLogger(Constants.class);

    private static String StaticPath = null;

    public static synchronized String getStaticPath() {
        if (StaticPath == null) {
            try {
                StaticPath = ResourceUtils.getURL("classpath:static").getPath().replace("%20", " ");
                if (StaticPath != null && StaticPath.length() > 3 && StaticPath.indexOf(":") > 0) {
                    if (StaticPath.indexOf("/") == 0)
                        StaticPath = StaticPath.substring(1);

                    if (!StaticPath.endsWith("/"))
                        StaticPath = StaticPath + "/";

                }
            } catch (FileNotFoundException e) {
                return "static/";
            }
        }
        return StaticPath;
    }

    private static String ConfigPath = null;

    public static synchronized String getConfigPath() {
        if (ConfigPath == null) {
            try {
                ConfigPath = ResourceUtils.getURL("classpath:config").getPath().replace("%20", " ");
                if (ConfigPath != null && ConfigPath.length() > 3 && ConfigPath.indexOf(":") > 0) {
                    if (ConfigPath.indexOf("/") == 0)
                        ConfigPath = ConfigPath.substring(1);
                    if (!ConfigPath.endsWith("/"))
                        ConfigPath = ConfigPath + "/";

                }
            } catch (FileNotFoundException e) {
                return "config/";
            }
        }
        return ConfigPath;
    }

    public static final Map<BPMEventModule, BPMTaskService> BPMServiceMap = new HashMap<>();

    public static String CompanyNameTitle = Configuration.readConfigString("company.name.title", "config/config");

    public static String CompanyFaceUrl = Configuration.readConfigString("company.face.url", "config/config");

    public static String MENU_GROUP_ICON = Configuration.readConfigString("menu.group.icon", "config/config");

    public static String MENU_MODULE_ICON = Configuration.readConfigString("menu.module.icon", "config/config");

    public static int StockAutoAlarmEnable = StringUtils
            .parseInt(Configuration.readConfigString("stock.alarm.auto.enable", "config/config"));

    public static String AppDomainServer = Configuration.readConfigString("ad.domain.server", "config/config");

    public static int AppDomainEnable = StringUtils
            .parseInt(Configuration.readConfigString("ad.domain.enable", "config/config"));

    public static String EngineerUserPath = Configuration.readConfigString("engineer.user.path", "config/config");

    private static List<BMSEmployee> EngineerUserList = new ArrayList<>();

    public static final int EngineerUserIDMin = Integer.MAX_VALUE - 47;

    public static synchronized List<BMSEmployee> GetEngineerUserList() {

        if (EngineerUserList == null || EngineerUserList.size() == 0) {
            try {
                File wFile = new File(EngineerUserPath);
                if (!wFile.exists()) {
                    wFile.createNewFile();
                }
                String wFileString = FileUtils.readFileToString(new File(EngineerUserPath), "UTF-8");
                if (StringUtils.isNotEmpty(wFileString)) {
                    EngineerUserList = JSON.parseArray(DesUtil.decrypt(wFileString, SessionConstants.appSecret),
                            BMSEmployee.class);
                }
            } catch (Exception e) {
                logger.error(e.toString());
            }
        }
        if (EngineerUserList == null) {
            EngineerUserList = new ArrayList<BMSEmployee>();
        }

        return CloneTool.CloneArray(EngineerUserList, BMSEmployee.class);
    }

    public static synchronized void SetEngineerUserList(List<BMSEmployee> wEngineerUserList) {
        try {

            if (wEngineerUserList == null)
                wEngineerUserList = new ArrayList<BMSEmployee>();
            EngineerUserList = CloneTool.CloneArray(wEngineerUserList, BMSEmployee.class);
            File wFile = new File(EngineerUserPath);
            if (!wFile.exists()) {
                wFile.createNewFile();
            }
            FileUtils.writeStringToFile(new File(EngineerUserPath),
                    DesUtil.encrypt(StringUtils.toJSONString(EngineerUserList), SessionConstants.appSecret), "UTF-8");
        } catch (Exception e) {
            logger.error(e.toString());
        }

    }


    public static int RoleManageEnable = StringUtils.parseInt(Configuration.readConfigString("role.manager.enable",
            "config/config"));

    public static String CHECK_AUTHOR_CER = "iPlant";

    public static String iPlant_resEncode_type = "UTF-8";

    public static int iPlant_timeout_seconds = 60;

    public static String IPLANT_RUN_TYPE_CLIENT = "client";
    public static String IPLANT_RUN_TYPE_WEB = "web";
    public static String IPLANT_RUN_TYPE_3TD = "3td";


    public static String Client_Upload_Save_Path = Configuration.readConfigString("client.upload.save.path",
            "config/config");
    public static String Client_Upload_Excel_Save_Path = Configuration.readConfigString("client.upload.excel.save.path",
            "config/config");

    // 邮件

    public static String EMAIL_SENDER = Configuration.readConfigString("iplant.mail.sender", "config/config");

    public static String EMAIL_RECEIVER = Configuration.readConfigString("iplant.mail.receiver", "config/config");
    public static String EMAIL_SENDER_PASSWORD = Configuration.readConfigString("iplant.mail.sender.password",
            "config/config");
    public static String EMAIL_SERVER_HOST = Configuration.readConfigString("iplant.mail.host", "config/config");
    public static String EMAIL_SERVER_PORT = Configuration.readConfigString("iplant.mail.port", "config/config");

    public static List<String> ImageSuffixList = new ArrayList<String>();


    /**
     * FTP服务器ip地址
     */
    public static String FTPServerURL = Configuration.readConfigString("ftp.server.ip", "config/config");

    /**
     * FTP端口，默认是21（注意：SSH默认22） port = 21;
     */
    public static int FTPServerPORT = StringUtils
            .parseInt(Configuration.readConfigString("ftp.server.port", "config/config"));

    /**
     * FTP登录用户名
     */
    public static String FTPUserName = Configuration.readConfigString("ftp.server.username", "config/config");
    /**
     * FTP登录密码
     */
    public static String FTPPassword = Configuration.readConfigString("ftp.server.password", "config/config");

    /**
     * FTP 访问文件夹
     */
    public static String FTPServerDir = Configuration.readConfigString("ftp.server.dir", "config/config");


    public static int AuthCompareType = BFCAuthCompares.MD5.getValue();


    private static BFCAuthRecord _AuthRecord = null;

    private static LockHelper mLockHelper = LockHelper.getLock(Constants.class);

    public static BFCAuthRecord GetAuthRecord() {
        if (_AuthRecord != null)

            return _AuthRecord;

        synchronized (mLockHelper) {
            if (_AuthRecord != null)
                return _AuthRecord;

            //默认等于本机实际硬件，且直接过期
            _AuthRecord = BFCAuthRecord.GetDefaultValue();
            _AuthRecord.FullAuthRecord();

            String wFilePath = getConfigPath() + "/AuthFiles/授权文件.txt";
            File wFile = new File(wFilePath);
            if (wFile.exists()) {
                try {
                    List<String> wTextString = Files.readAllLines(wFile.toPath());
                    //启动载入，载入前对比
                    String wText = StringUtils.Join("", wTextString);
                    if (StringUtils.isEmpty(wText))
                        return _AuthRecord;
                    wText = DesUtil.decrypt(wText);

                    BFCAuthRecord wBFCAuthRecord = JSON.parseObject(wText, BFCAuthRecord.class);

                    if (wBFCAuthRecord == null)
                        return _AuthRecord;

                    //检查通过则判定可以直接复制授权内容
                    if (wBFCAuthRecord.Compare(_AuthRecord, AuthCompareType))
                        _AuthRecord = wBFCAuthRecord;
                } catch (Exception ex) {
                    logger.error("mAuthRecord start Read Error:{}", ex.getMessage());
                }
            } else if (wFilePath.startsWith("config/")) {
                _AuthRecord = null;
            }
        }
        return _AuthRecord;
    }

    public static void SetAuthRecord(BFCAuthRecord wBFCAuthRecord) {
        _AuthRecord = wBFCAuthRecord;
        try {
            String wFilePath = getConfigPath() + "/AuthFiles/授权文件.txt";
            File wFile = new File(wFilePath);
            if (!wFile.exists()) {
                wFile.mkdirs();
                if (wFile.exists()) {
                    wFile.delete();
                }
            }

            Files.write(wFile.toPath(), StringUtils.parseListArgs(DesUtil.encrypt(JSON.toJSONString(_AuthRecord))));
        } catch (Exception ex) {
            logger.error("AuthRecord write Error:{}", ex.getMessage());
        }
    }


    static {

        try {


            ImageSuffixList = StringUtils
                    .parseList(Configuration.readConfigString("upload.image.suffix", "config/config").split(","));
            if (ImageSuffixList == null)
                ImageSuffixList = new ArrayList<String>();

            ImageSuffixList.removeIf(p -> StringUtils.isEmpty(p));

            if (ImageSuffixList.size() == 0) {
                ImageSuffixList = StringUtils
                        .parseList(new String[]{"jpg", "jpeg", "png", "ico", "icon", "gif", "bpm", "dwg", "svg"});
            }

            int _AuthCompareType = StringUtils.parseInt(Configuration.readConfigString("role.manager.compareType",
                    "config/config"));

            if (_AuthCompareType > 0 && _AuthCompareType < (BFCAuthCompares.Server.getValue() * 2))
                AuthCompareType = _AuthCompareType;

        } catch (Exception e) {
            logger.error(StringUtils.Format("{0} {1} Error:{2}", "Constants", "static", e.toString()));
        }

    }

    // region APP 客户端版本文件
    private static Calendar RefreshBFCClientTime = Calendar.getInstance();

    private static BFCClientConfig BFCClientConfig_APP;

    public static synchronized BFCClientConfig getBFCClientConfig_APP() {
        if (BFCClientConfig_APP == null || RefreshBFCClientTime.compareTo(Calendar.getInstance()) <= 0) {
            BFCClientConfig_APP = XmlTool.ReadXml(Constants.getConfigPath() + "APPClientConfig.xml");

            RefreshBFCClientTime.add(Calendar.MINUTE, 3);

            if (BFCClientConfig_APP == null) {
                BFCClientConfig_APP = new BFCClientConfig();
                XmlTool.SaveXml(Constants.getConfigPath() + "APPClientConfig.xml", BFCClientConfig_APP);
            }
        }

        return BFCClientConfig_APP;
    }
    // endRegion

    // region 视频转码

    public static List<String> VideoChangeSource = new ArrayList<String>();

    // endRegion
}
